home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume3 / pcmail / part03 < prev    next >
Encoding:
Internet Message Format  |  1989-02-03  |  57.4 KB

  1. Path: xanth!mcnc!ece-csc!ncsuvx!lll-winken!lll-tis!ames!necntc!ncoast!allbery
  2. From: wswietse@eutrc3.UUCP (Wietse Venema)
  3. Newsgroups: comp.sources.misc
  4. Subject: v03i004: uucp mail for pc's (3 of 8)
  5. Message-ID: <212@eutrc3.UUCP>
  6. Date: 20 Apr 88 16:45:27 GMT
  7. Sender: allbery@ncoast.UUCP
  8. Reply-To: wswietse@eutrc3.UUCP (Wietse Venema)
  9. Organization: Tech. Univ. Eindhoven, Neth.
  10. Lines: 2025
  11. Approved: allbery@ncoast.UUCP
  12.  
  13. comp.sources.misc: Volume 3, Issue 4
  14. Submitted-By: "Wietse Venema" <wswietse@eutrc3.UUCP>
  15. Archive-Name: pcmail/Part3
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 3 (of 8)."
  24. # Contents:  Installation cmail.c dir.c file.c gphys.c kphys.c
  25. #   makefile.uts xpres.c
  26. # Wrapped by wietse@eutwc1 on Wed Apr 20 16:45:16 1988
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f Installation -a "${1}" != "-c" ; then 
  29.   echo shar: Will not over-write existing file \"Installation\"
  30. else
  31. echo shar: Extracting \"Installation\" \(7515 characters\)
  32. sed "s/^X//" >Installation <<'END_OF_Installation'
  33. XTHE UNIX SIDE OF THE CONNECTION
  34. X
  35. XThe pc-mail programs will need a UNIX host to  exchange  messages
  36. Xwith.  This  automatically gives access to other networks. I sug-
  37. Xgest the following strategy:
  38. X
  39. X - Get a uucp login, say, uuxyz on a UNIX system. This will  also
  40. Xbecome the uucp-node name of the pc. The file /usr/lib/uucp/L.sys
  41. Xshould be extended with an entry, e.g.
  42. X
  43. X uuxyz Passive
  44. X
  45. X(on some systems one has to use `Never' instead of `Passive'). It
  46. Xmay also be necessary to update the /usr/lib/uucp/USERFILE.
  47. X
  48. X - Have all mail for user uuxyz forwarded to  uuxyz!somebody.  On
  49. XBSD  UNIX  systems,  this  is  achieved  by  placing  the address
  50. X`uuxyz!somebody' in  a  file  ~uuxyz/.forward;  on  System-V  one
  51. Xshould  put  the  text  `Forward  to  uuxyz!somebody' in the file
  52. X/usr/mail/uuxyz, which should be read/writeable by group mail.
  53. X
  54. XIn the above examples, somebody is a  name  that  can  be  freely
  55. Xchosen;  it  will  not  be used by the pc. Of course, mail can be
  56. Xforwarded to uuxyz!somebody from other accounts as well.
  57. X
  58. XThe result of all this is that you can send mail to any  user  on
  59. Xthe UNIX host by just specifying her login name; the host name of
  60. Xyour pc will not appear in mail headers. People can send mail  to
  61. Xyou  by  specifying an address on the UNIX host. There is no need
  62. Xto register the pc in the uucp maps.
  63. X
  64. XIf the above strategy is not what you  like,  you  will  have  to
  65. Xoperate  as  a  "real"  uucp node and should #define UUCP_HOST in
  66. Xsendwork.c. You should also be registered as a uucp  node.  There
  67. Xis more discussion about this in sendwork.c
  68. X
  69. XAs a minimum, the UNIX host should support the standard uucp  `g'
  70. Xprotocol.  This  protocol was developed for eight-bit data paths.
  71. XUnfortunately, modern networks often eat up  XON/XOFF  and  other
  72. Xcontrol characters.
  73. X
  74. XTo handle non-transparent networks  I  have  written  a  protocol
  75. Xcalled  `k'. It has been used with the Eindhoven University Sytek
  76. Xnetwork for over two years and is part of the  pc-mail  distribu-
  77. Xtion.  If  you're  really  desperate (and have UNIX source) build
  78. Xthis protocol into the uucico program  by  adding  the  following
  79. Xline to struct Proto Ptbl[] in cntrl.c:
  80. X
  81. X 'k', kturnon, krdmsg, kwrmsg, krddata, kwrdata, kturnoff,
  82. X
  83. Xand linking the uucico objects with kio.c  kp.h  kphys.c  kpres.c
  84. Xand ktrans.c.
  85. X
  86. XTHE PC SIDE OF THE CONNECTION
  87. X
  88. XTo bring pc-mail up, edit the makefile to reflect the system  you
  89. Xare  using  (there  are  separate makefiles for UNIX and MS-DOS).
  90. XThe MS-DOS makefile is for a UNIX-compatible make utility  posted
  91. Xto  usenet  near  the  end of 1986. There is a batch command file
  92. X(buidall.bat) for those who do not have  a  unix-compatible  make
  93. Xutility.  For testing purposes it is convenient to run this stuff
  94. Xon a UNIX host.
  95. X
  96. XSaying `make' should produce five programs:
  97. X
  98. X - mail, the menu-driven user interface
  99. X - cmail, a program that checks if there is new mail
  100. X - smail, a program that queues messages for  transmission  after
  101. X          doing alias substitution on mail addresses
  102. X - cico, the program that performs dialups and file transfers
  103. X - rmail, extracts "From" info from mail received by cico
  104. X
  105. XThe programs access a common data base in the  form  of  a  spool
  106. Xdirectory  with  setup  file,  logfile  and  message files. There
  107. Xshould be no  other  files  in  the  spool  directory,  to  avoid
  108. Xconfusion.  You  will  have  to  create  the spool directory; the
  109. Xprograms will not do that.
  110. X
  111. XYou will have to set some environment  variables  before  running
  112. Xthe mail program.
  113. X
  114. X - MAILDIR, the absolute path to your spool directory
  115. X - EDITOR, the name of your favourite editor program
  116. X - PATH, in order locate the executables
  117. X
  118. XThe editor command may be an MS-DOS batch file; in that case  you
  119. Xshould include the '.bat' suffix in the command name.
  120. X
  121. XThe following two environment variables are optional.
  122. X
  123. X - MAILPRN, if printer output should not go to PRN
  124. X - MAILCMD, command that is executed when the mail program  exits
  125. X
  126. XAlso,  make  sure  that  the limit on the number of open files is
  127. Xlarge enough (20 or so). On MS-DOS, this is  handled  by  a  line
  128. X`files=20' in the CONFIG.SYS file.
  129. X
  130. XRun the interactive mail program and choose the setup command. On
  131. XMS-DOS  systems  only  the  com1  port  is  supported  (see  file
  132. Xcomport.s). Here is my setup (some  names  changed)  for  getting
  133. Xthrough the TUE port selector:
  134. X
  135. X    communications_port: com1
  136. X    baud_rate:           1200
  137. X    remote_host_name:    eutwc1
  138. X    login_name:          uutest
  139. X    dialup_sequence:     atm\r OK atdt455215\r CONNECT \0 ease: xyz\r ease: 
  140. Xxyz\r choice: 1\r called: b076\r CLOSED \r
  141. X    disconnect_sequence: \0
  142. X
  143. XAll entries must be filled or the  cico  program  will  complain.
  144. XThe MS-DOS version supports the com1 port only.
  145. X
  146. XThe dial-up sequence requires some explanation. Basically it is a
  147. Xlist  of words separated by whitespace. The first word is sent to
  148. Xthe comm. port. The program  will  wait  until  it  receives  the
  149. Xsecond word. And so on. Unlike real uucp (or kermit), there is no
  150. Xretry facility. The backslash escape sequences  are  stolen  from
  151. Xthe c programming language, with some extensions:
  152. X
  153. X \b    backspace
  154. X \f    formfeed
  155. X \n    linefeed
  156. X \r    carriage return
  157. X \s    blank
  158. X \t    tab
  159. X \\    backslash
  160. X \nnn    octal code for a character
  161. X
  162. XIn order to send or expect an empty string, use the \0 sequence.
  163. X
  164. XIt is not possible to send null characters. The dial-up  sequence
  165. Xshould terminate when the UNIX host displays its "login:" prompt;
  166. Xthe remainder of the dialup sequence is built into the  software.
  167. XThis,  and  having  (pc  node  name)  == (uucp login name) are to
  168. Xprevent fraud. Thus,  assuming  a  Hayes-compatible  modem,  your
  169. Xdialup sequence could be as simple as:
  170. X
  171. X    atm\r OK atdt455215\r CONNECT \0 
  172. X
  173. XWhen this dialup sequence succeeds, the  program  continues  with
  174. Xits built-in sequence:
  175. X
  176. X    ogin: login_name\r ssword: your_password\r
  177. X
  178. XThe disconnect sequence uses the same  escape  sequences  as  the
  179. Xdial-up  sequence,  but does not use the send/expect protocol. In
  180. Xthe above sequence, the disconnect sequence is an empty string.
  181. X
  182. XIf the cico program has problems communicating with the UNIX host
  183. Xyou can run it by hand, for example:
  184. X
  185. X cico -d 9 -p your_password
  186. X
  187. Xwhich will  produce  a  lot  of  debugging  output.  Setting  the
  188. Xdebugging  level  to less than 9 produces less output. Level 4 is
  189. Xsufficient to monitor the dial-up and login sequence.
  190. X
  191. XALIAS DATABASE
  192. X
  193. XThe user can define aliases for (groups of) mail  addresses.  The
  194. Xformat  of  the alias data base is simple: it is a text file with
  195. Xon each line:
  196. X
  197. X alias replacement part
  198. X
  199. XThe replacement  part  may  be  one  or  more  words;  words  are
  200. Xseparated  by  blanks,  tabs  or commas. Whenever the smail (mail
  201. Xspooler) program recognizes an  alias,  it  is  replaced  by  the
  202. X`replacement'  part.  Aliases  may  be  defined in terms of other
  203. Xaliases; also the order in which they appear in  the  alias  data
  204. Xbase  is not important (except when an alias is defined more than
  205. Xonce; the program  remembers  only  the  last  definition  of  an
  206. Xalias).  The  alias  expansion software is smart enough to detect
  207. Xinfinite loops and to suppress multiple occurrances of  the  same
  208. Xrecipient. Alias substitution is not case-sensitive.
  209. X
  210. XBATCH-MODE OPERATION
  211. X
  212. XThe cmail program can be run from a batch file (say each time the
  213. Xpc  is  turned on), contact the UNIX host, and report if there is
  214. Xnew mail. Also, you may want to auto-execute  the  cmail  command
  215. Xwhen exiting from the interactive mail shell. See the manual page
  216. Xin the cmail.c source.
  217. X
  218. END_OF_Installation
  219. if test 7515 -ne `wc -c <Installation`; then
  220.     echo shar: \"Installation\" unpacked with wrong size!
  221. fi
  222. # end of overwriting check
  223. fi
  224. if test -f cmail.c -a "${1}" != "-c" ; then 
  225.   echo shar: Will not over-write existing file \"cmail.c\"
  226. else
  227. echo shar: Extracting \"cmail.c\" \(3509 characters\)
  228. sed "s/^X//" >cmail.c <<'END_OF_cmail.c'
  229. X/*++
  230. X/* NAME
  231. X/*    cmail 1
  232. X/* SUMMARY
  233. X/*    report if there are unread messages
  234. X/* PROJECT
  235. X/*    pc-mail
  236. X/* PACKAGE
  237. X/*    cmail
  238. X/* SYNOPSIS
  239. X/*    cmail [-p password]
  240. X/* DESCRIPTION
  241. X/*    cmail reports if there are unread mail messages in the
  242. X/*    pc-mail spool directory.
  243. X/*    
  244. X/*    If the -p option is present, cmail first invokes the cico
  245. X/*    program to contact the mail server host.
  246. X/*
  247. X/*    Typically cmail is run immediately after system startup,
  248. X/*    while you are getting your first cup of coffee.
  249. X/*
  250. X/*    The program returns a nonzero exit status if it could not 
  251. X/*    find any mail.
  252. X/* COMMANDS
  253. X/*    cico    file transfer program
  254. X/*    rmail    processes new mail
  255. X/* FILES
  256. X/*    Various files in the spool directory
  257. X/*
  258. X/*    LOGFILE system status messages
  259. X/*    n<seqno> mail messages
  260. X/*    h<seqno> header line of new mail
  261. X/*    o<seqno> header line of old mail
  262. X/* DIAGNOSTICS
  263. X/*    Error messages in case the environment is not properly set up.
  264. X/* BUGS
  265. X/*    Invites people to put their mail password into the autoexec file.
  266. X/* AUTHOR(S)
  267. X/*    W.Z. Venema
  268. X/*    Eindhoven University of Technology
  269. X/*    Department of Mathematics and Computer Science
  270. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  271. X/* CREATION DATE
  272. X/*    Sun Apr  3 19:34:57 MET 1988
  273. X/* LAST MODIFICATION
  274. X/*    Wed Apr  6 00:18:45 MET 1988
  275. X/* VERSION/RELEASE
  276. X/*    1.3
  277. X/*--*/
  278. X
  279. X#include <signal.h>
  280. X
  281. X#include "defs.h"
  282. X#include "dir.h"
  283. X#include "path.h"
  284. X#include "status.h"
  285. X
  286. Xhidden void parse_args();        /* forward declarations */
  287. Xhidden void usage();
  288. Xhidden void error();
  289. Xhidden int newmail();
  290. X
  291. Xhidden char *password = 0;        /* set by the -p option */
  292. X
  293. Xmain(argc,argv)
  294. Xint argc;
  295. Xchar **argv;
  296. X{
  297. X    signal(SIGINT,SIG_IGN);        /* disable ctrl-c */
  298. X    parse_args(argc,argv);        /* parse command args */
  299. X    if (pathinit())            /* check path info */
  300. X    error("cmail: bad MAILDIR environment variable");
  301. X    if (password && *password && 
  302. X    invokelp(CICO,"-p",password,(char *)0) == E_NOPROG)
  303. X    error("cmail: cannot execute the CICO program");
  304. X    if (invokelp(RMAIL,(char *)0) == E_NOPROG)
  305. X    error("cmail: cannot execute the RMAIL program");
  306. X    exit(newmail() == 0);                /* look for new mail */
  307. X}
  308. X
  309. X/* parse_args - process command-line arguments */
  310. X
  311. Xhidden void parse_args(argc,argv)
  312. Xint argc;
  313. Xchar **argv;
  314. X{
  315. X    while (--argc && *++argv && **argv == '-') {    /* process options */
  316. X    switch (*++*argv) {
  317. X    case 'p':                    /* call cico first */
  318. X        if (--argc == 0)
  319. X        usage("missing password");
  320. X        password = *++argv;
  321. X        break;
  322. X    default:                    /* unknown option */
  323. X        usage(strcons("invalid option: -%s",*argv));
  324. X        break;
  325. X    }
  326. X    }
  327. X
  328. X    /* check for extraneous arguments */
  329. X
  330. X    if (argc > 0)
  331. X    usage(strcons("unexpected argument: %s",*argv));
  332. X}
  333. X
  334. X/* scan for new unread mail */
  335. X
  336. Xhidden int newmail()
  337. X{
  338. X    register int dd;
  339. X    int pfxlen = sizeof(HDRPFX)-1;
  340. X    char *f;
  341. X    FILE *fp;
  342. X    char from[BUFSIZ];
  343. X    register int msgcount = 0;
  344. X
  345. X    /*
  346. X    * Scan the spool directory for unread messages and extract
  347. X    * the originator address from the corresponding meta file.
  348. X    */
  349. X
  350. X    for (dd = opendir(maildir); f = readdir(dd); /* void */) {
  351. X    int seqno;
  352. X    if (strncmp(f,HDRPFX,pfxlen) == 0 && sscanf(f+pfxlen,"%d",&seqno)) {
  353. X        if (fp = fopen(new_meta(seqno),"r")) {
  354. X        fgets(from,BUFSIZ,fp);
  355. X        printf("You have new mail from %s",from);
  356. X        msgcount++;
  357. X        fclose(fp);
  358. X        }
  359. X    }
  360. X    }
  361. X    closedir(dd);
  362. X    return(msgcount);
  363. X}
  364. X
  365. Xhidden void error(str)
  366. Xchar *str;
  367. X{
  368. X    fprintf(stderr,"%s\n",str);
  369. X    exit(1);
  370. X}
  371. X
  372. Xhidden void usage(str)
  373. Xchar *str;
  374. X{
  375. X    fprintf(stderr,"%s\nusage: cmail [-p password]\n",str);
  376. X    exit(1);
  377. X}
  378. END_OF_cmail.c
  379. if test 3509 -ne `wc -c <cmail.c`; then
  380.     echo shar: \"cmail.c\" unpacked with wrong size!
  381. fi
  382. # end of overwriting check
  383. fi
  384. if test -f dir.c -a "${1}" != "-c" ; then 
  385.   echo shar: Will not over-write existing file \"dir.c\"
  386. else
  387. echo shar: Extracting \"dir.c\" \(6998 characters\)
  388. sed "s/^X//" >dir.c <<'END_OF_dir.c'
  389. X/*++
  390. X/* NAME
  391. X/*      opendir,readdir,closedir 3
  392. X/* SUMMARY
  393. X/*      directory search functions
  394. X/* PROJECT
  395. X/*      dos/unix compatibility
  396. X/* PACKAGE
  397. X/*      library routines
  398. X/* SYNOPSIS
  399. X/*      int opendir(path)
  400. X/*      char *path;
  401. X/*
  402. X/*      char *readdir(id)
  403. X/*      int dir;
  404. X/*
  405. X/*      closedir(id)
  406. X/*      int id;
  407. X/* DESCRIPTION
  408. X/*      This package provides a system-independent interface to the file system
  409. X/*      that allows a program to simultaneously scan one or more directories.
  410. X/*
  411. X/*    The MS-DOS version accepts both forward and backward slash as
  412. X/*    field delimiter in path names.
  413. X/*
  414. X/*      opendir() accepts a valid path and returns an id which should be used 
  415. X/*      in subsequent calls of readdir()....closedir().
  416. X/*
  417. X/*      readdir() returns a pointer to a character string with the next file in
  418. X/*      the directory associated with id, or a null pointer. 
  419. X/*
  420. X/*      closedir() terminates the directory search and deallocates
  421. X/*      memory used to keep track of `certain important data'.
  422. X/* FUNCTIONS AND MACROS
  423. X/*      myalloc()
  424. X/* DIAGNOSTICS
  425. X/*      opendir() returns -1 if all slots are in use.
  426. X/*      Specifying a wrong id is considered a fatal error condition.
  427. X/*      Memory allocation errors cause the program to terminate.
  428. X/* BUGS
  429. X/*      readdir() returns a pointer to memory
  430. X/*      whose contents is overwritten with each call.
  431. X/*
  432. X/*    Despite whatthe names suggest, these functions are not compatible
  433. X/*    with the BSD directory access routines.
  434. X/*
  435. X/*    Does not work with unix file systems that have variable-length
  436. X/*    directory entries (BSD).
  437. X/* AUTHOR(S)
  438. X/*      Wietse Venema
  439. X/*      Eindhoven University of Technology
  440. X/*      Department of Mathematics and Computer Science
  441. X/*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  442. X/* CREATION DATE
  443. X/*      Mon Nov 17 19:38:19 GMT+1:00 1986
  444. X/* LAST MODIFICATION
  445. X/*    Mon Apr  4 23:38:43 MET 1988
  446. X/* VERSION/RELEASE
  447. X/*    1.3
  448. X/*--*/
  449. X
  450. X#include "defs.h"
  451. X#include "dir.h"
  452. X
  453. X#ifdef    unix
  454. X#   include <sys/types.h>
  455. X#   include <sys/dir.h>
  456. X#endif
  457. X
  458. X#ifdef    MSDOS
  459. X#   include <dos.h>
  460. X#   include <ctype.h>
  461. X
  462. Xhidden void badslot();            /* forward declarations */
  463. Xhidden void lowcpy();
  464. X
  465. X/* 
  466. X* The Disk Transfer Area as used by MS-DOS when it finds a file name 
  467. X* during a wild-card scan.
  468. X*/
  469. X
  470. X#define MAXNAME         13      /* max size of MS-DOS file name + null byte */
  471. X
  472. Xtypedef struct Dta {
  473. X    char reserved[21];          /* start of dta buffer */ 
  474. X    char found;                 /* attribute found */
  475. X    short time;                 /* file's time */
  476. X    short date;                 /* file's date */
  477. X    int losize;                 /* low order file size */
  478. X    int hisize;                 /* high-order file size */
  479. X    char name[MAXNAME];         /* name of file terminated by zero byte */
  480. X} Dta;
  481. X
  482. X/* macros for easy access to registers with MS-DOS system calls */
  483. X
  484. X#define AH              regs.h.ah               /* ah register */
  485. X#define BX              regs.x.bx               /* bx register */
  486. X#define CX              regs.x.cx               /* cx register */
  487. X#define DX              regs.x.dx               /* dx register */
  488. X#define CF              regs.x.cflag            /* cflag register */
  489. X#define INT             intdos(®s,®s)     /* dos system call */
  490. X#define WORD            (unsigned)              /* cast */
  491. X
  492. X#define SET_DTA(d)      { AH = 0x1a; DX = WORD d; INT; }
  493. X#define GET_DTA(d)      { AH = 0x2f; INT; d = BX; }
  494. X#define GET_1ST(f,n)    { AH = 0x4e; CX = 0x10; DX = WORD n; INT; f = CF; }
  495. X#define GET_NXT(f)      { AH = 0x4f; CX = 0x10; INT; f = CF; }
  496. X
  497. X/* information about directory accesses is kept in a table with initially */
  498. X/* empty slots */
  499. X
  500. X#define MAXSLOT 20              /* nbr of directories that can be processed */
  501. X
  502. Xtypedef struct Slot {
  503. X    unsigned int dsave;         /* temp storage for disk transfer address */
  504. X    unsigned int cstat;         /* MS-DOS system call return status */
  505. X    Dta dta;                    /* disk transfer area */
  506. X} Slot;
  507. X
  508. Xhidden Slot *dirslots[20];      /* slots with pointers */
  509. X
  510. X#endif    /* MSDOS */
  511. X
  512. X/* opendir - set up for directory search */
  513. X
  514. X#ifdef    MSDOS
  515. X
  516. Xpublic int opendir(name)
  517. Xchar *name;
  518. X{
  519. X    register int id;
  520. X    register Slot *q;
  521. X    char buf[BUFSIZ];
  522. X    union REGS regs;                    /* cpu registers in system call */
  523. X    char lch;
  524. X
  525. X    for (id = 0; id < MAXSLOT && dirslots[id]; id++)
  526. X    ;                               /* search first free slot */
  527. X    if (id < MAXSLOT) {                 /* found a free slot */
  528. X    dirslots[id] = q = (Slot *) myalloc(sizeof(Slot));
  529. X    GET_DTA(q->dsave);              /* save dta address */
  530. X    SET_DTA(&q->dta);               /* set to current dta */
  531. X    strcpy(buf,name);               /* construct search path */
  532. X    if (*name && index("\\/:",name[strlen(name)-1]) == 0)
  533. X        strcat(buf,"/");
  534. X    strcat(buf,"*.*");              /* append wildest possible file name */
  535. X    GET_1ST(q->cstat,buf);          /* start search (read one name ahead) */
  536. X    SET_DTA(q->dsave);              /* restore dta address */
  537. X    return(id);                     /* return offset in slots table */
  538. X    } else {
  539. X    return(-1);                     /* no free slot available */
  540. X    }
  541. X}
  542. X
  543. X#endif    /* MSDOS */
  544. X
  545. X/* readdir - return next file in directory or null string */
  546. X
  547. X#ifdef    unix
  548. X
  549. Xpublic char *readdir(id)
  550. Xint id;
  551. X{
  552. X    static struct direct ent[2];
  553. X
  554. X    for (;;) {
  555. X    if (read(id,(char *) ent,sizeof(*ent)) != sizeof(*ent))
  556. X        return(0);
  557. X    if (ent[0].d_ino != 0)
  558. X        return(ent[0].d_name);
  559. X    }
  560. X}
  561. X
  562. X#endif    /* unix */
  563. X
  564. X#ifdef    MSDOS
  565. X
  566. Xpublic char *readdir(id)
  567. Xint id;
  568. X{
  569. X    register Slot *q;
  570. X    union REGS regs;
  571. X    static char buf[MAXNAME];
  572. X
  573. X    if (id < 0 || id >= MAXSLOT || (q = dirslots[id]) == 0) {
  574. X    badslot("readdir",id);        /* serves you well! */
  575. X    /* NOTREACHED */
  576. X    } else if (q->cstat) {
  577. X    return(0);            /* no name found */
  578. X    } else {
  579. X    lowcpy(buf,q->dta.name);        /* keep name (lower case) */
  580. X    GET_DTA(q->dsave);              /* save dta address */
  581. X    SET_DTA(&q->dta);               /* setup to search */
  582. X    GET_NXT(q->cstat);              /* for the next entry */
  583. X    SET_DTA(q->dsave);              /* in the directory */
  584. X    return buf;                     /* return name */
  585. X    }
  586. X}
  587. X
  588. X#endif    /* MSDOS */
  589. X
  590. X/* closedir - release directory access slot */
  591. X
  592. X#ifdef    MSDOS
  593. X
  594. Xpublic int closedir(id)
  595. Xint id;
  596. X{
  597. X    register Slot **p;
  598. X
  599. X    if (id < 0 || id >= MAXSLOT || *(p = dirslots+id) == 0) {
  600. X    badslot("closedir",id);
  601. X    /* NOTREACHED */
  602. X    } else {
  603. X    free((char *)*p);               /* deallocate slot */
  604. X    *p = 0;                         /* mark as unused */
  605. X    return(0);
  606. X    }
  607. X}
  608. X
  609. X#endif    /* MSDOS */
  610. X
  611. X#ifdef    MSDOS
  612. X
  613. X/* badslot - the program is obviously corrupted. stop it. */
  614. X
  615. Xhidden void badslot(name,id)
  616. Xchar *name;
  617. Xint id;
  618. X{
  619. X    fatal("%s: bad slot: %d\n",name,id);
  620. X}
  621. X
  622. X/* lowcpy - copy string and map to lower case */
  623. X
  624. Xhidden void lowcpy(out,in)
  625. Xchar *out;
  626. Xchar *in;
  627. X{
  628. X    register char *d = out;
  629. X    register char c;
  630. X    register char *s = in;
  631. X
  632. X    while (c = *s++)
  633. X    *d++ = isupper(c) ? tolower(c) : c;
  634. X    *d = '\0';
  635. X}
  636. X
  637. X#endif    /* MSDOS */
  638. END_OF_dir.c
  639. if test 6998 -ne `wc -c <dir.c`; then
  640.     echo shar: \"dir.c\" unpacked with wrong size!
  641. fi
  642. # end of overwriting check
  643. fi
  644. if test -f file.c -a "${1}" != "-c" ; then 
  645.   echo shar: Will not over-write existing file \"file.c\"
  646. else
  647. echo shar: Extracting \"file.c\" \(6599 characters\)
  648. sed "s/^X//" >file.c <<'END_OF_file.c'
  649. X/*++
  650. X/* NAME
  651. X/*      file 3
  652. X/* SUMMARY
  653. X/*      manipulate ordinary files
  654. X/* PROJECT
  655. X/*      pc-mail
  656. X/* PACKAGE
  657. X/*      mailsh
  658. X/* SYNOPSIS
  659. X/*      int file()
  660. X/*
  661. X/*    int junk_file()
  662. X/* DESCRIPTION
  663. X/*      file() is called when the user selected the "file" option
  664. X/*    in the main menu. The pager displays a directory listing on the
  665. X/*      screen. The user may then walk through the file display and
  666. X/*    select a file or directory. 
  667. X/*
  668. X/*    In case a regular file is selected the user may specify
  669. X/*    an action (send file as mail, delete file, display
  670. X/*    file, print file, copy file to workfile for subsequent
  671. X/*    editing etc.).
  672. X/*
  673. X/*    junk_file() should be invoked when the file display is no longer
  674. X/*    valid.
  675. X/* FILES
  676. X/*      By selecting directory files the user can walk through the whole
  677. X/*      file system.
  678. X/* SEE ALSO
  679. X/*      kbdinp(3), pager(3)
  680. X/* BUGS
  681. X/*    On some MS-DOS systems, we never get the ".." entry.
  682. X/*    This is an unsolved problem.
  683. X/*
  684. X/*    Changing the current directory may cause problems if
  685. X/*    the MAILDIR and EDITOR environment variables hold
  686. X/*    relative path names.
  687. X/*
  688. X/*    No provision to change default drive on MS-DOS systems.
  689. X/* AUTHOR(S)
  690. X/*      W.Z. Venema
  691. X/*      Eindhoven University of Technology
  692. X/*      Department of Mathematics and Computer Science
  693. X/*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  694. X/* CREATION DATE
  695. X/*      Sun Apr  5 17:18:06 GMT+1:00 1987
  696. X/* LAST MODIFICATION
  697. X/*    Mon Apr  4 23:40:13 MET 1988
  698. X/* VERSION/RELEASE
  699. X/*    1.3
  700. X/*--*/
  701. X
  702. X#include <time.h>
  703. X#include <sys/types.h>
  704. X#include <sys/stat.h>
  705. X#include <ctype.h>
  706. X#include "defs.h"
  707. X#include "screen.h"
  708. X#include "pager.h"
  709. X#include "mailsh.h"
  710. X#include "dir.h"
  711. X#include "path.h"
  712. X#include "status.h"
  713. X#include "window.h"
  714. X
  715. Xextern struct tm *localtime();          /* std C library */
  716. X
  717. Xhidden File *bldlist();            /* forward declaration */
  718. Xhidden int show_list();
  719. Xhidden int pick_file();
  720. Xhidden int delfile();
  721. Xhidden int show_file();
  722. Xhidden int rmfile();
  723. X
  724. Xhidden File *dfile = 0;            /* file listing */
  725. Xhidden File *dirfile = 0;               /* directory listing */
  726. X
  727. X/* file - called from keyboard interpreter, call keyboard driver */
  728. X
  729. Xpublic int file()
  730. X{
  731. X    static Screen screen[] = {
  732. X    'C',    "Close",        0,      initscreen,
  733. X    'P',    "Print",        print,    "Print file listing",
  734. X    'S',    "Save",         save,    "Save file listing to ordinary file",
  735. X    PGUP,    PgUp,        pu_pager,pageup,
  736. X    PGDN,    PgDn,        pd_pager,pagedn,
  737. X    UP,    "Up",           up_pager,csrup,
  738. X    DOWN,    "Down",         dn_pager,csrdn,
  739. X    ENTER,    "Enter",        pick_file,"Display file at cursor",
  740. X    0,    0,              show_list,
  741. X    "To display a file, select it with cursor keys, then press ENTER",
  742. X    };
  743. X
  744. X    kbdinp(screen);            /* set up dialogue */
  745. X    close_pager(dirfile);        /* deallocate pager file */
  746. X    dirfile = 0;            /* say it's gone */
  747. X    return(S_REDRAW);            /* force screen update */
  748. X}
  749. X
  750. X/* show_list - create or refresh file listing */
  751. X
  752. Xhidden int show_list()
  753. X{
  754. X    if (dirfile == 0) {            /* no pager file? */
  755. X    patience();
  756. X    dirfile = bldlist();        /* create one */
  757. X    } else {
  758. X    set_pager(dirfile);        /* select existing pager file */
  759. X    }
  760. X    ds_pager();                /* display the thing */
  761. X    return(0);                /* say screen is up-to-date */
  762. X}
  763. X
  764. X/* bldlist - build file listing display */
  765. X
  766. Xhidden File *bldlist()
  767. X{
  768. X    register int dd = opendir(THISDIR);    /* start directory search */
  769. X    register File *pp = open_pager();    /* allocate pager file */
  770. X    register char *f;            /* file name pointer */
  771. X
  772. X    while (f = readdir(dd)) {        /* read next file name */
  773. X    struct stat s;
  774. X    if (stat(f,&s) == 0) {        /* get file info (size, date) */
  775. X        app_pager(pp,strcons("%-20s %9ld %s",f,
  776. X        s.st_size,tstamp(&s.st_mtime)));
  777. X    } else {
  778. X        app_pager(pp,f);
  779. X    }
  780. X    }
  781. X    sort_pager(pp,FORW_SORT);        /* sort by file name */
  782. X    closedir(dd);            /* directory search done */
  783. X    return(pp);                /* current pager file */
  784. X}
  785. X
  786. X/* pick_file - display selected file or change directory */
  787. X
  788. Xhidden int pick_file()
  789. X{
  790. X    static char botline[80];
  791. X    static Screen screen[] = {
  792. X    'C',    "Close",        0,      "Return to file listing",
  793. X    'D',    "Delete",    delfile,"Delete this file",
  794. X    'M',    "Mail",        mailfile,"Mail a copy of this file",
  795. X    'P',    "Print",        print,    "Print this file",
  796. X    'S',    "Save",         save,    "Save a copy to an ordinary file",
  797. X    'W',    "Work",        makework,"Save a copy to a work file",
  798. X    PGUP,    PgUp,        pu_pager,pageup,
  799. X    PGDN,    PgDn,        pd_pager,pagedn,
  800. X    UP,    "Up",           up_pager,csrup,
  801. X    DOWN,    "Down",         dn_pager,csrdn,
  802. X    0,    0,              show_file,
  803. X    botline,
  804. X    };
  805. X    struct stat s;
  806. X
  807. X    if (scan_pager(dirfile,"%s",message) == 0) {    /* cannot read name */
  808. X    beep();                        /* "notify" user */
  809. X    return(0);                    /* nothing happened */
  810. X    } else if (access(message,04) || stat(message,&s)) {/* cannot read file */
  811. X    beep();                        /* "notify" user */
  812. X    return(0);                    /* nothing happened */
  813. X    } else if ((s.st_mode&S_IFMT) == S_IFDIR) {         /* directory file */
  814. X    chdir(message);                    /* change directory */
  815. X    close_pager(dirfile);                /* purge display */
  816. X    dirfile = bldlist();                /* new file display */
  817. X    return(S_REDRAW);                /* update display */
  818. X    } else {                                            /* ordinary file */
  819. X     sprintf(botline,"(Reading file \"%s\")",message);
  820. X    kbdinp(screen);                    /* look at screen */
  821. X    close_pager(dfile);                /* and forget it */
  822. X    dfile = 0;                    /* say it's gone */
  823. X    return(S_REDRAW);                               /* force redrawing */
  824. X    }
  825. X}
  826. X
  827. X/* show_file - create or refresh display of selected file */
  828. X
  829. Xhidden int show_file()
  830. X{
  831. X    if (dfile) {
  832. X    set_pager(dfile);                /* select dispay */
  833. X    } else {
  834. X    if (rd_pager(dfile = open_pager(),message))    /* try to read file */
  835. X        mesg_pager(dfile,m_msgread);        /* read error */
  836. X    }
  837. X    ds_pager();                        /* rewrite screen */
  838. X    return(0);                        /* screen up-to-date */
  839. X}
  840. X
  841. X/* delfile - ask confirmation before removing a file */
  842. X
  843. Xhidden int delfile()
  844. X{
  845. X    static Screen screen[] = {
  846. X    ESCCR,    0,        rmfile,int_error,
  847. X    0,    0,        0,
  848. X    "Press ESC to cancel. Confirm with ENTER",
  849. X    };
  850. X
  851. X    return(kbdinp(screen)|S_REDRAW);        /* "are you sure?" */
  852. X}
  853. X
  854. X/* rmfile - actually remove file */
  855. X
  856. Xhidden int rmfile()
  857. X{
  858. X    if (unlink(message)) {            /* try to remove file */
  859. X    errdisp(E_UNLINK);            /* notify the user */
  860. X    return(S_BREAK|S_REDRAW);        /* redisplay, stop caller */
  861. X    } else {
  862. X    junk_file();                /* say file display outdated */
  863. X    return(S_BREAK);            /* terminate caller */
  864. X    }
  865. X}
  866. X
  867. X/* junk_file - directory listing is no longer up to date */
  868. X
  869. Xpublic int junk_file()
  870. X{
  871. X    if (dirfile) {
  872. X    close_pager(dirfile);            /* close pager file */
  873. X    dirfile = 0;                /* say it is gone */
  874. X    }
  875. X    return(0);                    /* in case we need that */
  876. X}
  877. END_OF_file.c
  878. if test 6599 -ne `wc -c <file.c`; then
  879.     echo shar: \"file.c\" unpacked with wrong size!
  880. fi
  881. # end of overwriting check
  882. fi
  883. if test -f gphys.c -a "${1}" != "-c" ; then 
  884.   echo shar: Will not over-write existing file \"gphys.c\"
  885. else
  886. echo shar: Extracting \"gphys.c\" \(6855 characters\)
  887. sed "s/^X//" >gphys.c <<'END_OF_gphys.c'
  888. X/*++
  889. X/* NAME
  890. X/*    gphys 3
  891. X/* SUMMARY
  892. X/*    g protocol packet input/output
  893. X/* PROJECT
  894. X/*    pc-mail
  895. X/* PACKAGE
  896. X/*    cico
  897. X/* SYNOPSIS
  898. X/*    #include "gp.h"
  899. X/*
  900. X/*    void gsctrl(fd,c)
  901. X/*    int fd,c;
  902. X/*
  903. X/*    void gsdata(fd,pk,c)
  904. X/*    int fd,c;
  905. X/*    Packet *pk;
  906. X/*
  907. X/*    int grpack(fd,pk)
  908. X/*    int fd;
  909. X/*    Packet *pk;
  910. X/* DESCRIPTION
  911. X/*    The functions in this module send and receive packets. Interfacing
  912. X/*    is based on Packet structures. Messages are interpreted elsewhere.
  913. X/*
  914. X/*    gsctrl() sends a control packet to the remote receiver (no data
  915. X/*    segment).
  916. X/*
  917. X/*    gsdata() sends a data packet to the remote receiver. 
  918. X/*    The Packet structure is completed with a 16-bit checksum.
  919. X/*    This function expects read/write sequence information in 
  920. X/*    the c parameter.
  921. X/*
  922. X/*    grpack() receives a packet from the remote transmitter and checks
  923. X/*    its integrity. It fills in the k, c, len and check fields of the 
  924. X/*    Packet structure and returns the type of message (DATA, SHORT, 
  925. X/*    CLOSE, RJ, RR, etcetera).
  926. X/* DIAGNOSTICS
  927. X/*    grpack() returns FAIL if a corrupted packet was received, and
  928. X/*    TIME if no packet was received within the time-out interval.
  929. X/* BUGS
  930. X/*    No data re-reading in case of transmission errors.
  931. X/*    Some parts of the code rely on 8-bit bytes, 16-bit short integers.
  932. X/* AUTHOR(S)
  933. X/*    W.Z. Venema
  934. X/*    Eindhoven University of Technology
  935. X/*    Department of Mathematics and Computer Science
  936. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  937. X/* CREATION DATE
  938. X/*    Sun Apr 19 11:39:27 GMT+1:00 1987
  939. X/* LAST MODIFICATION
  940. X/*    Mon Apr  4 23:41:15 MET 1988
  941. X/* VERSION/RELEASE
  942. X/*    1.3
  943. X/*--*/
  944. X
  945. X#include <signal.h>
  946. X#include <setjmp.h>
  947. X#include "gp.h"
  948. X
  949. X/* local and forward declarations */
  950. X
  951. Xstatic jmp_buf timebuf;
  952. Xstatic int chksum(),readhead(),readdata(),clkint();
  953. X
  954. X#define    READ(fd,cp,n)    { if (read(fd,cp,n) != n) clkint(); }
  955. X
  956. X/*
  957. X* "A six byte framing envelope is constructed using the control"
  958. X* "byte C of a packet and five other bytes as depicted below."
  959. X*        <DLE><k><c0><c1><C><x>
  960. X* "The <DLE> symbol denotes the ASCII ctrl/P character. If the"
  961. X* "envelope is to be followed by a data segment, <k> has the"
  962. X* "value log2(size)-4; i.e. 1 <= k < 8. If k is 9, then the"
  963. X* "envelope represents a control packet. The <c0> and <c1>"
  964. X* "bytes are the low-order and high-order bytes respectively of"
  965. X* "0xAAA minus a 16-bit checksum. For control packets, this"
  966. X* "16-bit checksum is the same as the control byte C. For data"
  967. X* "packets, the checksum is calculated by the program below."
  968. X* "The <x> byte is the exclusive-or of <k><c0><c1><C>. Error"
  969. X* "control is accomplished by checking a received framing"
  970. X* "envelope for compliance with the definition, and comparing a"
  971. X* "checksum function of the data segment with <c0><c1>."
  972. X*/
  973. X
  974. X/* gsctrl - send control packet (no data segment) */
  975. X
  976. Xvoid gsctrl(fd,c)
  977. Xint fd,c;
  978. X{
  979. X    char header[6];
  980. X    register char chkhdr;
  981. X    register char *cp = header;
  982. X    int cksm = MAGIC-c;                /* do checksum */
  983. X
  984. X    *cp++ = CTRL('P');                /* start of header */
  985. X    chkhdr  = *cp++ = KCTRL;            /* k byte (control) */
  986. X    chkhdr ^= *cp++ = cksm;            /* c0 byte (checksum lsb) */
  987. X    chkhdr ^= *cp++ = cksm>>8;            /* c1 byte (checksum msb) */
  988. X    chkhdr ^= *cp++ = c;            /* message|sequence info */
  989. X    *cp = chkhdr;                /* header checksum */
  990. X
  991. X    write(fd,header,sizeof(header));        /* send header */
  992. X    DEBUG(9,"xmt: %o\n",c&0377);        /* show header */
  993. X}
  994. X
  995. X/* gsdata - send data packet */
  996. X
  997. Xvoid gsdata(fd,pk,c)
  998. Xint fd,c;
  999. Xregister Packet *pk;
  1000. X{
  1001. X    char header[6];
  1002. X    register char chkhdr;
  1003. X    register char *cp = header;
  1004. X    int cval = pk->c|(c&077);            /* fold in sequence info */
  1005. X
  1006. X    pk->chk = MAGIC-(chksum(pk->data,pk->len)^(0377&cval));
  1007. X
  1008. X    *cp++ = CTRL('P');                /* start of header */
  1009. X    chkhdr  = *cp++ = pk->k;            /* k byte (message length) */
  1010. X    chkhdr ^= *cp++ = pk->chk;            /* c0 byte (checksum lsb) */
  1011. X    chkhdr ^= *cp++ = pk->chk>>8;        /* c1 byte (checksum msb) */
  1012. X    chkhdr ^= *cp++ = cval;            /* data|sequence info */
  1013. X    *cp = chkhdr;                /* header checksum */
  1014. X
  1015. X    write(fd,header,sizeof(header));        /* send header */
  1016. X    DEBUG(9,"xmt: %o\n",cval&0377);        /* show header */
  1017. X
  1018. X    write(fd,pk->data,pk->len);            /* send data segment */
  1019. X    DEBUG(9,"xmt: data %d bytes\n",pk->segl);    /* show data */
  1020. X}
  1021. X
  1022. X/* grpack - receive one data or control packet; return packet type info */
  1023. X
  1024. Xint grpack(fd,pk)
  1025. Xint fd;
  1026. Xregister Packet *pk;
  1027. X{
  1028. X    if (setjmp(timebuf))            /* in case we time out */
  1029. X    return(TIME);                /* it just happened */
  1030. X    signal(SIGALRM,clkint);            /* alarm clock response */
  1031. X    alarm(ALARM);                /* set alarm clock */
  1032. X
  1033. X    if (readhead(fd,pk)) {            /* read packet header */
  1034. X    DEBUG(7,"rcv: bad header\n","");
  1035. X    alarm(0);                /* turn timer off */
  1036. X    return(FAIL);                /* header checksum error */
  1037. X    } else if (pk->k == KCTRL) {
  1038. X    alarm(0);                /* turn timer off */
  1039. X    return(MESG(pk->c));            /* CLOSE | RJ | RR etcetera */
  1040. X    } else if (readdata(fd,pk)) {
  1041. X    DEBUG(7,"rcv: bad data\n","");
  1042. X    alarm(0);                /* turn timer off */
  1043. X    return(FAIL);                /* data checksum error */
  1044. X    } else {
  1045. X    alarm(0);                /* turn timer off */
  1046. X    return(TYPE(pk->c));            /* DATA | SHORT */
  1047. X    }
  1048. X}
  1049. X
  1050. X/* readhead - read header and check header checksum */
  1051. X
  1052. Xstatic int readhead(fd,pk)
  1053. Xint fd;
  1054. Xregister Packet *pk;
  1055. X{
  1056. X    char header[5];
  1057. X    int ok;
  1058. X    register char chkhdr;
  1059. X    register char *cp = header;
  1060. X
  1061. X    do {                    /* start reading */
  1062. X    READ(fd,cp,1);                /* skip all garbage */
  1063. X    } while (*cp != CTRL('P'));            /* up to packet header */
  1064. X
  1065. X    READ(fd,header,sizeof(header));        /* read packet header */
  1066. X
  1067. X    chkhdr  = pk->k = *cp++;            /* data length or control */
  1068. X    chkhdr ^= pk->chk = *cp++&0377;        /* data checksum lsb */
  1069. X    chkhdr ^= *cp;
  1070. X    pk->chk |= (*cp++&0377)<<8;    /* data checksum msb */
  1071. X    chkhdr ^= pk->c = *cp++;            /* control packet or data */
  1072. X    if (ok = (chkhdr == *cp))
  1073. X    DEBUG(9,"rcv: %o\n",pk->c&0377);
  1074. X    return(!ok);                /* check the checksum */
  1075. X}
  1076. X
  1077. X/* readdata - read data segment and check data checksum */
  1078. X
  1079. Xstatic int readdata(fd,pk)
  1080. Xint fd;
  1081. Xregister Packet *pk;
  1082. X{
  1083. X    if (seglen[pk->k] > pk->len) {
  1084. X    DEBUG(7,"rcv: data %d bytes too big\n",seglen[pk->k]);
  1085. X    return(1);
  1086. X    } else {
  1087. X    register int i;
  1088. X    DEBUG(9,"rcv: data %d bytes\n",pk->len = seglen[pk->k]);
  1089. X    for (i = 0; i < pk->len; i++) {
  1090. X        READ(fd,&pk->data[i],1);
  1091. X    }
  1092. X    return(pk->chk+(chksum(pk->data,pk->len)^(pk->c&0377)) != MAGIC);
  1093. X    }
  1094. X}
  1095. X
  1096. X/* clkint - tiny time-out routine */
  1097. X
  1098. Xstatic int clkint()
  1099. X{
  1100. X    DEBUG(9,"rcv: timed out\n","");
  1101. X    longjmp(timebuf,1);
  1102. X    /* NOTREACHED */
  1103. X}
  1104. X
  1105. X/* chksum - unix packet driver checksum algorithm */
  1106. X
  1107. Xstatic int chksum(s,n)
  1108. Xregister char *s;
  1109. Xregister n;
  1110. X{
  1111. X    register short sum;
  1112. X    register unsigned short t;
  1113. X    register short x;
  1114. X
  1115. X    sum = -1;
  1116. X    x = 0;
  1117. X    do {
  1118. X    if (sum < 0) {
  1119. X        sum <<= 1;
  1120. X        sum++;
  1121. X    } else
  1122. X        sum <<= 1;
  1123. X    t = sum;
  1124. X    sum += (unsigned)*s++ & 0377;
  1125. X    x += sum ^ n;
  1126. X    if ((unsigned short)sum <= t) {
  1127. X        sum ^= x;
  1128. X    }
  1129. X    } while (--n > 0);
  1130. X
  1131. X    return(sum);
  1132. X}
  1133. END_OF_gphys.c
  1134. if test 6855 -ne `wc -c <gphys.c`; then
  1135.     echo shar: \"gphys.c\" unpacked with wrong size!
  1136. fi
  1137. # end of overwriting check
  1138. fi
  1139. if test -f kphys.c -a "${1}" != "-c" ; then 
  1140.   echo shar: Will not over-write existing file \"kphys.c\"
  1141. else
  1142. echo shar: Extracting \"kphys.c\" \(7524 characters\)
  1143. sed "s/^X//" >kphys.c <<'END_OF_kphys.c'
  1144. X/*++
  1145. X/* NAME
  1146. X/*      kphys 3
  1147. X/* SUMMARY
  1148. X/*      k protocol packet exchange
  1149. X/* PACKAGE
  1150. X/*      uucp across the TUEnet
  1151. X/* SYNOPSIS
  1152. X/*      #include "kp.h"
  1153. X/*
  1154. X/*      kspack(fd,type,num,size,data) 
  1155. X/*      int fd, num, size;
  1156. X/*      char type, data[MAXPACKSIZ];
  1157. X/*
  1158. X/*      krpack(fd,num,size,data)
  1159. X/*      int fd, *num, *size;
  1160. X/*      char data[MAXPACKSIZ];
  1161. X/* DESCRIPTION
  1162. X/*      The functions in this file take care of data framing and verification. 
  1163. X/*
  1164. X/*      Kspack() sends a packet of the specified type and number,
  1165. X/*      and with len data bytes.
  1166. X/*
  1167. X/*      Krpack() tries to receive a packet and returns: the packet type plus
  1168. X/*      size and data, or TIME (no packet) or FAIL (bad checksum).
  1169. X/*
  1170. X/*      The data format has been derived from kermit implementations:
  1171. X/*
  1172. X/* .nf
  1173. X/* .in +5
  1174. X/*      SOH     packet header, ASCII control-P
  1175. X/*      len     (size of data, low 6 bits) + 32
  1176. X/*      len     (size of data, high 6 bits) + 32
  1177. X/*      num     (packet number mod 64) + 32
  1178. X/*      type    packet type
  1179. X/*      check   one-byte type-1 kermit checksum
  1180. X/*
  1181. X/*      The header is followed by checksummed data if len >0:
  1182. X/*
  1183. X/* .nf
  1184. X/* .in +5
  1185. X/*      data    len data bytes
  1186. X/*      check1  (upper 2 bits of type-3 kermit 16-bit checksum) + 32
  1187. X/*      check2  (middle 6 bits of type-3 kermit 16-bit checksum) + 32
  1188. X/*      check3  (lower 6 bits of type-3 kermit 16-bit checksum) + 32
  1189. X/*
  1190. X/*      Every packet is followed by an ASCII carriage return, which is
  1191. X/*      ignored upon reception of a packet. It prevents timeout errors
  1192. X/*      when one byte gets lost (the most common case).
  1193. X/* BUGS
  1194. X/*      It is yet another convention for data framing.
  1195. X/* AUTHOR(S)
  1196. X/*      Wietse Venema
  1197. X/*      Eindhoven University of Technology
  1198. X/*      Department of Mathematics and Computer Science
  1199. X/*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  1200. X/* CREATION DATE
  1201. X/*      Mon Feb  3 13:38:14 MET 1986
  1202. X/* LAST MODIFICATION
  1203. X/*    Mon Apr  4 23:43:13 MET 1988
  1204. X/* VERSION/RELEASE
  1205. X/*    1.5
  1206. X/*--*/
  1207. X
  1208. X#include <signal.h>
  1209. X#include <setjmp.h>
  1210. X#include "kp.h"
  1211. X
  1212. X#define READS(fd,ch)    {if (read(fd,&ch,1) < 0) clkint(); if ((ch &= 0177) == SOH) goto SYNC;}
  1213. X
  1214. Xjmp_buf env;                /* Environment ptr for timeout longjump */
  1215. X
  1216. Xclkint()                                /* Timer interrupt handler */
  1217. X{
  1218. X    longjmp(env,TRUE);                  /* Tell krpack to give up */
  1219. X}
  1220. X
  1221. Xkspack(fd,type,num,len,data)
  1222. Xint fd;
  1223. Xchar type, *data;
  1224. Xint num, len;
  1225. X{
  1226. X    char chksum, header[6], chk[3];     /* Checksums, header */
  1227. X
  1228. X    DEBUG(7,"xmt: type %c\n",type);
  1229. X    if (len > 0)
  1230. X    DEBUG(7,"xmt: data %d\n",len);
  1231. X
  1232. X    header[0] = SOH;                    /* Packet marker (SOH) */
  1233. X    header[1] = tosix(len);             /* Send the character count */
  1234. X    chksum    = header[1];              /* Initialize the checksum */
  1235. X    header[2] = tosix(len>>OUT);        /* Send the character count */
  1236. X    chksum   += header[2];              /* Update checksum */
  1237. X    header[3] = tochar(num);            /* Packet number */
  1238. X    chksum   += header[3];              /* Update checksum */
  1239. X    header[4] = type;                   /* Packet type */
  1240. X    chksum   += header[4];              /* Update checksum */
  1241. X    chksum    = (((chksum&0300) >> 6)+chksum)&077; /* Compute header checksum */
  1242. X    header[5] = tochar(chksum);         /* Put it in the packet */
  1243. X    write(fd,header,6);                /* Send the header */
  1244. X
  1245. X    if (len > 0) {                      /* Make data packet */
  1246. X    write(fd,data,len);           /* Send data */
  1247. X    chk3(data,len,chk);           /* Compute 16-bit checksum */
  1248. X    write(fd,chk,3);              /* Send checksum */
  1249. X    }
  1250. X    write(fd,"\r",1);                   /* Extra-packet line terminator */
  1251. X}
  1252. X
  1253. Xkrpack(fd,num,len,data)
  1254. Xint fd;
  1255. Xint *num;                               /* Packet number */
  1256. Xint *len;                               /* Packet length */
  1257. Xchar *data;                             /* Packet data */
  1258. X{
  1259. X    int i;                              /* Data character number, loop exit */
  1260. X    char t,                             /* Current input character */
  1261. X    type,                           /* Packet type */
  1262. X    rchk[3],                        /* Data checksum from host */
  1263. X    cchk[3],                        /* Data checksum computed here */
  1264. X    cchksum,                        /* Our (computed) checksum */
  1265. X    rchksum;                        /* Header checksum from other host */
  1266. X
  1267. X    if (setjmp(env)) {
  1268. X    DEBUG(7,"rcv: timed out\n","");
  1269. X    return TIME;                    /* Timed out */
  1270. X    }
  1271. X    signal(SIGALRM,clkint);             /* Setup the timeout */
  1272. X    alarm(TIMEOUT);
  1273. X
  1274. X    for (;;)                            /* Wait for packet header */
  1275. X    READS(fd,t);
  1276. XSYNC:                                   /* Got SOH */
  1277. X    alarm(TIMEOUT);
  1278. X    DEBUG(7,"rcv: found sync\n","");
  1279. X    READS(fd,t);                        /* Get character */
  1280. X    cchksum = t;                        /* Start the checksum */
  1281. X    *len = unchar(t);                   /* Character count, low six bits */
  1282. X
  1283. X    READS(fd,t);                        /* Get character */
  1284. X    cchksum += t;                       /* Update checksum */
  1285. X    *len += (unchar(t)<<OUT);           /* Character count, high six bits */
  1286. X
  1287. X    READS(fd,t);                        /* Get character */
  1288. X    cchksum += t;                       /* Update checksum */
  1289. X    *num = unchar(t);                   /* Packet number */
  1290. X
  1291. X    READS(fd,t);                        /* Get character */
  1292. X    cchksum += t;                       /* Update checksum */
  1293. X    type = t;                           /* Packet type */
  1294. X
  1295. X    READS(fd,t);                        /* Get header checksum */
  1296. X    rchksum = unchar(t);                /* Convert to numeric */
  1297. X    /* Fold in bits 7,8 to compute */
  1298. X    cchksum = (((cchksum&0300) >> 6)+cchksum)&077; /* header checksum */
  1299. X
  1300. X    if (cchksum != rchksum) {
  1301. X    DEBUG(7,"rcv: bad header\n","");
  1302. X    alarm(0);                       /* Disable the timer interrupt */
  1303. X    return FAIL;
  1304. X    } 
  1305. X    DEBUG(7,"rcv: type %c\n",type);
  1306. X
  1307. X    if ((*len > 0) && (data != NULLP))
  1308. X    {
  1309. X    for (i=0; i<*len; i++)          /* The data itself, if any */
  1310. X    {                               /* Loop for character count */
  1311. X        READS(fd,t);                /* Get character */
  1312. X        data[i] = t;                /* Keep data */
  1313. X    }
  1314. X
  1315. X    for (i=0; i<3; i++)             /* 16-bit CRC checksum */
  1316. X    {
  1317. X        READS(fd,t);                /* Get character */
  1318. X        rchk[i] = t;                /* Keep data */
  1319. X    }
  1320. X
  1321. X    chk3(data,*len,cchk);           /* Compute CRC */
  1322. X    if (strncmp(rchk,cchk,3)) {     /* Check with received CRC */
  1323. X        DEBUG(7,"rcv: bad data\n","");
  1324. X        alarm(0);                   /* Disable the timer interrupt */
  1325. X        return FAIL;
  1326. X    }
  1327. X    DEBUG(7,"rcv: data %d\n",*len);
  1328. X    }
  1329. X    alarm(0);                /* Disable the timer interrupt */
  1330. X    return(type);                       /* All OK, return packet type */
  1331. X}
  1332. X
  1333. X/*  C H K 3  --  Compute a type-3 Kermit block check.  */
  1334. X/*
  1335. XCalculate the 16-bit CRC of a string using a byte-oriented
  1336. Xtableless algorithm invented by Andy Lowry (Columbia University).  The
  1337. Xmagic number 010201 is derived from the CRC-CCITT polynomial x^16+x^12+x^5+1.
  1338. X*/
  1339. Xstatic chk3(s,len,chk) 
  1340. Xchar *s, *chk; 
  1341. Xint len; 
  1342. X{
  1343. X    unsigned int c, q;
  1344. X    long crc = 0;
  1345. X
  1346. X    while (len--) {
  1347. X    c = *s++;
  1348. X    q = (crc ^ c) & 017;            /* Low-order nibble */
  1349. X    crc = (crc >> 4) ^ (q * 010201);
  1350. X    q = (crc ^ (c >> 4)) & 017;     /* High order nibble */
  1351. X    crc = (crc >> 4) ^ (q * 010201);
  1352. X    }
  1353. X    *chk++ = tochar(((unsigned)(crc & 0170000)) >> 12);
  1354. X    *chk++ = tochar((crc & 07700) >> 6);
  1355. X    *chk++ = tochar(crc & 077);
  1356. X}
  1357. END_OF_kphys.c
  1358. if test 7524 -ne `wc -c <kphys.c`; then
  1359.     echo shar: \"kphys.c\" unpacked with wrong size!
  1360. fi
  1361. # end of overwriting check
  1362. fi
  1363. if test -f makefile.uts -a "${1}" != "-c" ; then 
  1364.   echo shar: Will not over-write existing file \"makefile.uts\"
  1365. else
  1366. echo shar: Extracting \"makefile.uts\" \(6491 characters\)
  1367. sed "s/^X//" >makefile.uts <<'END_OF_makefile.uts'
  1368. X# c compiler flags
  1369. X# -DSIII    for AT&T unix System-III or System-V
  1370. X#        for V7, BSD
  1371. XCFLAGS    = -DSIII -g
  1372. X
  1373. X# library options
  1374. X# -lcurses    for AT&T unix
  1375. X# -ltermcap    for V7, BSD
  1376. XLIBS    = -lcurses
  1377. X
  1378. X# lint options
  1379. X# -ML        for Microport
  1380. XLINTFL    = -Ml
  1381. X
  1382. XRETRIEVE= retrieve -d .arch
  1383. X
  1384. XSOURCES    = README ascf.c ascf.h call.c cico.c cmail.c comm.c comm.h \
  1385. X    connect.c defs.h desk.c deskutil.c dir.c \
  1386. X    dir.h email.c errdisp.c file.c getwork.c gp.h \
  1387. X    gphys.c gpres.c gtrans.c invoke.c kbdinp.c kio.c kp.h \
  1388. X    kphys.c kpres.c ktrans.c logs.c logs.h mailfile.c \
  1389. X    mailsh.c makework.c mbox.c myalloc.c \
  1390. X    newseqno.c pager.c pager.h params.c params.h path.c path.h \
  1391. X    protomsg.c rmail.c rmtname.c scanwork.c screen.c screen.h \
  1392. X    sendwork.c setup.c smail.c spoolfil.c startup.c \
  1393. X    status.h switcher.c sysdep.h window.c window.h \
  1394. X    work.h xpres.c comport.s str.c alias.c edit.c submit.c \
  1395. X    unalias.c hsearch.c hsearch.h clmap.h comport.h hsearch.3 \
  1396. X    buildall.bat kproto.ms Watchit makefile.uts makefile.msc \
  1397. X    mailsh.h srctoman.sh Installation Implementation termcap
  1398. X
  1399. XSHSRC    = mailsh.c call.c desk.c file.c screen.c mbox.c kbdinp.c \
  1400. X    pager.c window.c setup.c errdisp.c invoke.c path.c myalloc.c \
  1401. X    dir.c params.c newseqno.c email.c spoolfil.c ascf.c \
  1402. X    makework.c mailfile.c deskutil.c str.c alias.c edit.c submit.c
  1403. X
  1404. XSHOBJ    = mailsh.o call.o desk.o file.o screen.o mbox.o kbdinp.o \
  1405. X    pager.o window.o setup.o errdisp.o invoke.o path.o myalloc.o \
  1406. X    dir.o params.o newseqno.o email.o spoolfil.o ascf.o \
  1407. X    makework.o mailfile.o deskutil.o str.o alias.o edit.o submit.o
  1408. X
  1409. XSMSRC    = smail.c path.c dir.c newseqno.c ascf.c spoolfil.c str.c \
  1410. X    unalias.c hsearch.c
  1411. XSMOBJ    = smail.o path.o dir.o newseqno.o ascf.o spoolfil.o str.o \
  1412. X    unalias.o hsearch.o
  1413. X
  1414. XRMSRC    = rmail.c path.c dir.c str.c
  1415. XRMOBJ    = rmail.o path.o dir.o str.o
  1416. X
  1417. XCMSRC    = cmail.c path.c dir.c invoke.c str.c
  1418. XCMOBJ    = cmail.o path.o dir.o invoke.o str.o
  1419. X
  1420. XCISRC    = dir.c comm.c connect.c getwork.c kphys.c kpres.c ktrans.c logs.c \
  1421. X    cico.c myalloc.c newseqno.c params.c path.c protomsg.c rmtname.c \
  1422. X    scanwork.c sendwork.c startup.c switcher.c xpres.c \
  1423. X    gpres.c gtrans.c gphys.c str.c
  1424. X
  1425. XCIOBJ    = dir.o comm.o connect.o getwork.o kphys.o kpres.o ktrans.o logs.o \
  1426. X    cico.o myalloc.o newseqno.o params.o path.o protomsg.o rmtname.o \
  1427. X    scanwork.o sendwork.o startup.o switcher.o xpres.o \
  1428. X    gpres.o gtrans.o gphys.o str.o
  1429. X
  1430. Xall:    mail smail rmail cico cmail
  1431. X
  1432. X$(SOURCES):
  1433. X    $(RETRIEVE) $(SOURCES)
  1434. X
  1435. Xmail:    $(SHOBJ)
  1436. X    cc $(CFLAGS) -o mail $(SHOBJ) $(LIBS)
  1437. X
  1438. Xsmail:    $(SMOBJ)
  1439. X    cc $(CFLAGS) -o smail $(SMOBJ)
  1440. X
  1441. Xrmail:    $(RMOBJ)
  1442. X    cc $(CFLAGS) -o rmail $(RMOBJ)
  1443. X
  1444. Xcmail:    $(CMOBJ)
  1445. X    cc $(CFLAGS) -o cmail $(CMOBJ)
  1446. X
  1447. Xcico:    $(CIOBJ)
  1448. X    cc $(CFLAGS) -o cico $(CIOBJ)
  1449. X
  1450. Xmlint:
  1451. X    lint $(LINTFL) $(CFLAGS) $(SHSRC)
  1452. X
  1453. Xrlint:
  1454. X    lint $(LINTFL) $(CFLAGS) $(RMSRC)
  1455. X
  1456. Xslint:
  1457. X    lint $(LINTFL) $(CFLAGS) $(SMSRC)
  1458. X
  1459. Xclint:
  1460. X    lint $(LINTFL) $(CFLAGS) $(CISRC)
  1461. X
  1462. Xtar:    $(SOURCES)
  1463. X    tar cv $(SOURCES)
  1464. X
  1465. Xshar:    $(SOURCES)
  1466. X    find $(SOURCES) -print | makekit
  1467. X
  1468. Xdepend:
  1469. X    @grep '^# *include *"' *.c|sed 's/c:# *include *"\([^"]*\)".*/o:    \1/g'
  1470. X
  1471. Xalias.o:    defs.h
  1472. Xalias.o:    path.h
  1473. Xalias.o:    pager.h
  1474. Xalias.o:    mailsh.h
  1475. Xalias.o:    screen.h
  1476. Xalias.o:    status.h
  1477. Xascf.o:    defs.h
  1478. Xascf.o:    ascf.h
  1479. Xcall.o:    defs.h
  1480. Xcall.o:    path.h
  1481. Xcall.o:    screen.h
  1482. Xcall.o:    pager.h
  1483. Xcall.o:    mailsh.h
  1484. Xcico.o:    defs.h
  1485. Xcico.o:    logs.h
  1486. Xcico.o:    params.h
  1487. Xcico.o:    comm.h
  1488. Xcico.o:    status.h
  1489. Xcico.o:    path.h
  1490. Xcmail.o:    defs.h
  1491. Xcmail.o:    dir.h
  1492. Xcmail.o:    path.h
  1493. Xcmail.o:    status.h
  1494. Xcomm.o:    defs.h
  1495. Xcomm.o:    params.h
  1496. Xcomm.o:    comm.h
  1497. Xconnect.o:    defs.h
  1498. Xconnect.o:    params.h
  1499. Xconnect.o:    status.h
  1500. Xconnect.o:    comm.h
  1501. Xconnect.o:    logs.h
  1502. Xconnect.o:    sysdep.h
  1503. Xdesk.o:    defs.h
  1504. Xdesk.o:    mailsh.h
  1505. Xdesk.o:    path.h
  1506. Xdesk.o:    dir.h
  1507. Xdesk.o:    pager.h
  1508. Xdesk.o:    screen.h
  1509. Xdesk.o:    status.h
  1510. Xdesk.o:    window.h
  1511. Xdeskutil.o:    defs.h
  1512. Xdeskutil.o:    pager.h
  1513. Xdeskutil.o:    mailsh.h
  1514. Xdeskutil.o:    screen.h
  1515. Xdeskutil.o:    status.h
  1516. Xdir.o:    defs.h
  1517. Xdir.o:    dir.h
  1518. Xedit.o:    defs.h
  1519. Xedit.o:    path.h
  1520. Xedit.o:    mailsh.h
  1521. Xedit.o:    status.h
  1522. Xemail.o:    defs.h
  1523. Xemail.o:    path.h
  1524. Xemail.o:    dir.h
  1525. Xemail.o:    pager.h
  1526. Xemail.o:    screen.h
  1527. Xemail.o:    mailsh.h
  1528. Xemail.o:    status.h
  1529. Xerrdisp.o:    defs.h
  1530. Xerrdisp.o:    screen.h
  1531. Xerrdisp.o:    pager.h
  1532. Xerrdisp.o:    status.h
  1533. Xerrdisp.o:    window.h
  1534. Xfile.o:    defs.h
  1535. Xfile.o:    screen.h
  1536. Xfile.o:    pager.h
  1537. Xfile.o:    mailsh.h
  1538. Xfile.o:    dir.h
  1539. Xfile.o:    path.h
  1540. Xfile.o:    status.h
  1541. Xfile.o:    window.h
  1542. Xgetwork.o:    defs.h
  1543. Xgetwork.o:    logs.h
  1544. Xgetwork.o:    status.h
  1545. Xgetwork.o:    work.h
  1546. Xgetwork.o:    params.h
  1547. Xgetwork.o:    comm.h
  1548. Xgphys.o:    gp.h
  1549. Xgpres.o:    gp.h
  1550. Xgtrans.o:    gp.h
  1551. Xhsearch.o:    hsearch.h
  1552. Xinvoke.o:    defs.h
  1553. Xinvoke.o:    status.h
  1554. Xkbdinp.o:    defs.h
  1555. Xkbdinp.o:    mailsh.h
  1556. Xkbdinp.o:    screen.h
  1557. Xkbdinp.o:    window.h
  1558. Xkphys.o:    kp.h
  1559. Xkpres.o:    kp.h
  1560. Xktrans.o:    kp.h
  1561. Xlogs.o:    defs.h
  1562. Xlogs.o:    logs.h
  1563. Xlogs.o:    path.h
  1564. Xlogs.o:    status.h
  1565. Xmailfile.o:    defs.h
  1566. Xmailfile.o:    path.h
  1567. Xmailfile.o:    screen.h
  1568. Xmailfile.o:    mailsh.h
  1569. Xmailsh.o:    defs.h
  1570. Xmailsh.o:    path.h
  1571. Xmailsh.o:    status.h
  1572. Xmailsh.o:    mailsh.h
  1573. Xmailsh.o:    window.h
  1574. Xmakework.o:    defs.h
  1575. Xmakework.o:    path.h
  1576. Xmakework.o:    screen.h
  1577. Xmakework.o:    mailsh.h
  1578. Xmbox.o:    defs.h
  1579. Xmbox.o:    path.h
  1580. Xmbox.o:    pager.h
  1581. Xmbox.o:    screen.h
  1582. Xmbox.o:    mailsh.h
  1583. Xmyalloc.o:    defs.h
  1584. Xnewseqno.o:    defs.h
  1585. Xnewseqno.o:    path.h
  1586. Xnewseqno.o:    dir.h
  1587. Xpager.o:    defs.h
  1588. Xpager.o:    window.h
  1589. Xpager.o:    pager.h
  1590. Xpager.o:    path.h
  1591. Xpager.o:    ascf.h
  1592. Xparams.o:    defs.h
  1593. Xparams.o:    path.h
  1594. Xparams.o:    params.h
  1595. Xpath.o:    defs.h
  1596. Xpath.o:    path.h
  1597. Xpath.o:    status.h
  1598. Xprotomsg.o:    defs.h
  1599. Xprotomsg.o:    params.h
  1600. Xprotomsg.o:    comm.h
  1601. Xprotomsg.o:    logs.h
  1602. Xprotomsg.o:    status.h
  1603. Xrmail.o:    defs.h
  1604. Xrmail.o:    dir.h
  1605. Xrmail.o:    path.h
  1606. Xrmail.o:    status.h
  1607. Xrmtname.o:    defs.h
  1608. Xrmtname.o:    params.h
  1609. Xrmtname.o:    comm.h
  1610. Xrmtname.o:    logs.h
  1611. Xrmtname.o:    status.h
  1612. Xrmtname.o:    path.h
  1613. Xscanwork.o:    defs.h
  1614. Xscanwork.o:    params.h
  1615. Xscanwork.o:    comm.h
  1616. Xscanwork.o:    work.h
  1617. Xscanwork.o:    path.h
  1618. Xscanwork.o:    dir.h
  1619. Xscanwork.o:    logs.h
  1620. Xscreen.o:    defs.h
  1621. Xscreen.o:    screen.h
  1622. Xsendwork.o:    defs.h
  1623. Xsendwork.o:    work.h
  1624. Xsendwork.o:    logs.h
  1625. Xsendwork.o:    status.h
  1626. Xsendwork.o:    params.h
  1627. Xsendwork.o:    comm.h
  1628. Xsetup.o:    defs.h
  1629. Xsetup.o:    path.h
  1630. Xsetup.o:    screen.h
  1631. Xsetup.o:    mailsh.h
  1632. Xsetup.o:    pager.h
  1633. Xsetup.o:    params.h
  1634. Xsetup.o:    status.h
  1635. Xsetup.o:    window.h
  1636. Xsmail.o:    defs.h
  1637. Xsmail.o:    path.h
  1638. Xsmail.o:    status.h
  1639. Xspoolfil.o:    defs.h
  1640. Xspoolfil.o:    path.h
  1641. Xspoolfil.o:    ascf.h
  1642. Xspoolfil.o:    status.h
  1643. Xstartup.o:    defs.h
  1644. Xstartup.o:    params.h
  1645. Xstartup.o:    comm.h
  1646. Xstartup.o:    logs.h
  1647. Xstartup.o:    status.h
  1648. Xstartup.o:    sysdep.h
  1649. Xstr.o:    defs.h
  1650. Xsubmit.o:    defs.h
  1651. Xsubmit.o:    path.h
  1652. Xswitcher.o:    defs.h
  1653. Xswitcher.o:    work.h
  1654. Xswitcher.o:    params.h
  1655. Xswitcher.o:    comm.h
  1656. Xswitcher.o:    logs.h
  1657. Xswitcher.o:    status.h
  1658. Xunalias.o:    defs.h
  1659. Xunalias.o:    hsearch.h
  1660. Xunalias.o:    path.h
  1661. Xunalias.o:    ascf.h
  1662. Xwindow.o:    defs.h
  1663. Xwindow.o:    window.h
  1664. Xxpres.o:    defs.h
  1665. Xxpres.o:    params.h
  1666. Xxpres.o:    comm.h
  1667. Xxpres.o:    status.h
  1668. Xxpres.o:    sysdep.h
  1669. Xxpres.o:    logs.h
  1670. END_OF_makefile.uts
  1671. if test 6491 -ne `wc -c <makefile.uts`; then
  1672.     echo shar: \"makefile.uts\" unpacked with wrong size!
  1673. fi
  1674. # end of overwriting check
  1675. fi
  1676. if test -f xpres.c -a "${1}" != "-c" ; then 
  1677.   echo shar: Will not over-write existing file \"xpres.c\"
  1678. else
  1679. echo shar: Extracting \"xpres.c\" \(6821 characters\)
  1680. sed "s/^X//" >xpres.c <<'END_OF_xpres.c'
  1681. X/*++
  1682. X/* NAME
  1683. X/*      xpres 3
  1684. X/* SUMMARY
  1685. X/*      communications port i/o
  1686. X/* PROJECT
  1687. X/*      pc-mail
  1688. X/* PACKAGE
  1689. X/*      cico
  1690. X/* SYNOPSIS
  1691. X/*      xopen()
  1692. X/*
  1693. X/*      xclose()
  1694. X/*
  1695. X/*      xread(dummy,buf,len)
  1696. X/*      int dummy,len;
  1697. X/*      char *buf;
  1698. X/*
  1699. X/*      xwrite(dummy,buf,len)
  1700. X/*      int dummy,len;
  1701. X/*      char *buf;
  1702. X/*
  1703. X/*      xioctl(flag)
  1704. X/*      int flag;
  1705. X/* DESCRIPTION
  1706. X/*      The functions in this module perform functions analogous
  1707. X/*      to unix system calls, for the serial port of IBM-PC workalikes.
  1708. X/*
  1709. X/*      xopen() initializes a serial port. Also needed under UNIX.
  1710. X/*
  1711. X/*      xclose() closes a port.
  1712. X/*
  1713. X/*      xread(), xwrite() do not use their first argument. Under UNIX
  1714. X/*    one should use the standard read() and write() system calls.
  1715. X/*
  1716. X/*      xioctl() enables xon/xoff flow control if its argument
  1717. X/*      is nonzero. Not used under UNIX.
  1718. X/* SEE ALSO
  1719. X/*      comport.asm, IBM-PC comm routines by Tim Pozar
  1720. X/* DIAGNOSTICS
  1721. X/*      The read functions returns EOF in case of timeout; the write
  1722. X/*      function never detects any failure.
  1723. X/* BUGS
  1724. X/*      The xioctl() function is utterly primitive.
  1725. X/* AUTHOR(S)
  1726. X/*      MS-DOS parts derived from uuslave software (John Gilmore)
  1727. X/*    published on usenet early 1987. Bugs fixed & severely hacked by
  1728. X/*
  1729. X/*      W.Z. Venema
  1730. X/*      Eindhoven University of Technology
  1731. X/*      Department of Mathematics and Computer Science
  1732. X/*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  1733. X/* CREATION DATE
  1734. X/*      Sat Mar 28 23:01:43 GMT+1:00 1987
  1735. X/* LAST MODIFICATION
  1736. X/*    Mon Apr  4 23:51:55 MET 1988
  1737. X/* VERSION/RELEASE
  1738. X/*    1.3
  1739. X/*--*/
  1740. X
  1741. X#include "defs.h"
  1742. X#include "params.h"
  1743. X#include "comm.h"            /* baud rates, tty ports,... */
  1744. X#include "status.h"
  1745. X#include "sysdep.h"            /* other system dependencies */
  1746. X#include "logs.h"
  1747. X
  1748. X#ifdef    unix
  1749. X#   include <sgtty.h>
  1750. X#   include <signal.h>
  1751. X#   include <setjmp.h>
  1752. X#endif
  1753. X
  1754. X#ifdef    MSDOS
  1755. X#   define B(x)    (115200/(x))
  1756. X    static int sigint();
  1757. X    static void get_time();
  1758. X#endif
  1759. X
  1760. Xtypedef struct {            /* baud-rate lookup table */
  1761. X    char *name;
  1762. X    int code;
  1763. X} Baud_table;
  1764. X
  1765. XBaud_table btable[] = {
  1766. X#ifdef    unix
  1767. X    "50",    B50,
  1768. X    "75",    B75,
  1769. X    "110",    B110,
  1770. X    "134",    B134,
  1771. X    "150",    B150,
  1772. X    "300",    B300,
  1773. X    "600",    B600,
  1774. X    "1200",    B1200,
  1775. X    "1800",    B1800,
  1776. X    "2400",    B2400,
  1777. X    "4800",    B4800,
  1778. X    "9600",    B9600,
  1779. X#endif
  1780. X#ifdef    MSDOS
  1781. X    "50",    B(50),
  1782. X    "75",    B(75),
  1783. X    "110",    B(110),
  1784. X    "134",    B(134),
  1785. X    "150",    B(150),
  1786. X    "300",    B(300),
  1787. X    "600",    B(600),
  1788. X    "1200",    B(1200),
  1789. X    "1800",    B(1800),
  1790. X    "2400",    B(2400),
  1791. X    "4800",    B(4800),
  1792. X    "9600",    B(9600),
  1793. X#endif
  1794. X    0,        0,
  1795. X};
  1796. X
  1797. X/* xopen - open communications port; parameters taken from setup table */
  1798. X
  1799. Xxopen()
  1800. X{
  1801. X    register Baud_table *bp;
  1802. X#ifdef    unix
  1803. X    struct sgttyb ttmode;
  1804. X#endif
  1805. X
  1806. X    for (bp = btable; bp->name; bp++)        /* look up baud rate */
  1807. X    if (strcmp(bp->name,COMM_RATE) == 0)
  1808. X        break;
  1809. X    if (bp->name == 0) {            /* bad baud rate in setup */
  1810. X    debug(4)("Invalid baud rate %s\n",COMM_RATE);
  1811. X    exit(E_BADSETUP);
  1812. X    }
  1813. X
  1814. X#ifdef    unix
  1815. X    if ((ttfd = open(COMM_LINE,2)) < 0) {    /* try to access port */
  1816. X    debug(4)("Cannot access %s\n",COMM_LINE);
  1817. X    exit(E_BADSETUP);
  1818. X    }
  1819. X#ifndef SIII
  1820. X    if (ioctl(ttfd,TIOCEXCL))            /* exclusive access */
  1821. X    exit(E_BADSETUP);            /* not a terminal */
  1822. X#endif
  1823. X    ioctl(ttfd,TIOCHPCL);            /* hangup when done */
  1824. X    gtty(ttfd,&ttmode);                /* get port status */
  1825. X    ttmode.sg_ispeed = ttmode.sg_ospeed = bp->code;/* set baud rate */
  1826. X    ttmode.sg_flags |= (RAW);            /* raw mode */
  1827. X#ifdef    SIII
  1828. X    ttmode.sg_flags &= ~ECHO;
  1829. X#else
  1830. X    ttmode.sg_flags &= ~(ECHO|TANDEM|CBREAK);    /* no echo, crlf, flow ctrl */
  1831. X#endif
  1832. X    stty(ttfd,&ttmode);
  1833. X#endif
  1834. X
  1835. X#ifdef MSDOS
  1836. X    set_tty(bp->code);                /* set baud rate, DTR */
  1837. X    init_comm();                /* turn interrupts on */
  1838. X    signal(SIGINT,sigint);            /* must reset tty */
  1839. X    inp_flush();                /* flush garbage */
  1840. X    sleep(3);
  1841. X#endif
  1842. X}
  1843. X
  1844. X/* xclose - release the communications port */
  1845. X
  1846. Xxclose()
  1847. X{
  1848. X#ifdef    unix
  1849. X    close(ttfd);
  1850. X#endif
  1851. X
  1852. X#ifdef MSDOS
  1853. X    uninit_comm();
  1854. X#endif
  1855. X}
  1856. X
  1857. X/* xread - read from the serial port */
  1858. X
  1859. X#ifdef    MSDOS
  1860. X
  1861. Xxread(fd,buf,cnt)
  1862. Xint fd;
  1863. Xchar *buf;
  1864. Xregister int cnt;
  1865. X{
  1866. X    register char *p = buf;
  1867. X    register int c;
  1868. X
  1869. X    while (cnt > 0 && (c = xgetc()) != EOF) {
  1870. X    *p++ = c;
  1871. X    cnt--;
  1872. X    }
  1873. X    return(p-buf ? p-buf : -1);
  1874. X}
  1875. X#endif    /* MSDOS xwrite() */
  1876. X
  1877. X/* xgetc - read one character from serial port */
  1878. X
  1879. X#ifdef    unix
  1880. Xjmp_buf xbuf;
  1881. X
  1882. Xstatic timeout()                /* aux function for xgetc */
  1883. X{
  1884. X    longjmp(xbuf,1);
  1885. X}
  1886. X
  1887. Xxgetc()                        /* return next char */
  1888. X{
  1889. X    char ch;
  1890. X
  1891. X    if (setjmp(xbuf))                /* in case we time out */
  1892. X    return(EOF);                /* we just did */
  1893. X    signal(SIGALRM,timeout);            /* set timer response */
  1894. X    alarm(BYTE_TIMEOUT);            /* set timer */
  1895. X
  1896. X    read(ttfd,&ch,1);                /* go wait for character */
  1897. X    alarm(0);                    /* turn timer off */
  1898. X    return(ch&0377);                /* successfull termination */
  1899. X}
  1900. X#endif    /* unix xgetc() */
  1901. X
  1902. X#ifdef MSDOS
  1903. X
  1904. Xxgetc()
  1905. X{
  1906. X    char data;
  1907. X
  1908. X    int i;
  1909. X    unsigned s;
  1910. X    TIME n;
  1911. X
  1912. X    i = 0;
  1913. X    get_time(&n);
  1914. X    s = n.sec;
  1915. X
  1916. X    /*
  1917. X    * Implement timeouts by staring at the clock while we wait.
  1918. X    * When the second hand moves, bump our counter.  This is a lot
  1919. X    * easier than figuring out the time when we'd time out (in hours,
  1920. X    * minutes, and seconds!) and comparing against that, which is
  1921. X    * what people tend to do in Unix where the time is just an integer
  1922. X    * number of seconds.
  1923. X    */
  1924. X    while (i < BYTE_TIMEOUT) {
  1925. X    while (s == n.sec) {
  1926. X        if(inp_cnt() != 0) {
  1927. X        data = inp_char();
  1928. X        return (data & 0xFF);
  1929. X        }
  1930. X        get_time (&n);
  1931. X    }
  1932. X    s = n.sec;
  1933. X    ++i;
  1934. X    }
  1935. X    return(EOF);
  1936. X}
  1937. X
  1938. X/* xwrite - write buffer to serial port */
  1939. X
  1940. Xxwrite(fd,buf,ctr)
  1941. Xint fd;
  1942. Xregister char *buf;
  1943. Xint ctr;
  1944. X{
  1945. X    register int i = ctr;
  1946. X
  1947. X    while (i-- > 0)
  1948. X    outp_char(*buf++);
  1949. X    return ctr;
  1950. X}
  1951. X
  1952. X/*
  1953. X* Routines specific to MS-DOS
  1954. X* 
  1955. X* xioctl()    enable xon/xoff
  1956. X* get_timer()    read current time
  1957. X* sigint()    clean up interrupt handler and exit
  1958. X* sleep()    unix lookalike
  1959. X*/
  1960. X
  1961. X/* xioctl - enable xon/xoff protocol */
  1962. X
  1963. Xxioctl(flag)
  1964. Xint flag;
  1965. X{
  1966. X    set_xoff(flag);     /* Enable (flag != 0) or disable flow control */
  1967. X}
  1968. X
  1969. X/* sigint - restore terminal settings on dialout line */
  1970. X
  1971. Xstatic int sigint()
  1972. X{
  1973. X    uninit_comm();
  1974. X    reset_tty();
  1975. X    exit(0);
  1976. X}
  1977. X
  1978. X/* get_time - read time with dos call */
  1979. X
  1980. Xstatic void get_time(n)
  1981. XTIME_PTR n;
  1982. X{
  1983. X    union REGS inregs;
  1984. X    union REGS outregs;
  1985. X
  1986. X    inregs.h.ah = 0x2c;        /* Please make a #define for this, Tim */
  1987. X
  1988. X    int86(0x21, &inregs, &outregs);/* Please #define the 0x21 too */
  1989. X
  1990. X    n->hour = outregs.h.ch;
  1991. X    n->minute  = outregs.h.cl;
  1992. X    n->sec  = outregs.h.dh;
  1993. X    n->hsec = outregs.h.dl;
  1994. X}
  1995. X
  1996. X#define    get_sec(n)    (get_time(&n),n.sec)
  1997. X
  1998. Xsleep(x)
  1999. Xint x;
  2000. X{
  2001. X    TIME n;               /* current time record */
  2002. X    unsigned s = get_sec(n);
  2003. X
  2004. X    while (x-- > 0) {
  2005. X    while (s == get_sec(n))
  2006. X        /* void */ ;
  2007. X    s = n.sec;
  2008. X    }
  2009. X}
  2010. X
  2011. X#endif /* MSDOS */
  2012. END_OF_xpres.c
  2013. if test 6821 -ne `wc -c <xpres.c`; then
  2014.     echo shar: \"xpres.c\" unpacked with wrong size!
  2015. fi
  2016. # end of overwriting check
  2017. fi
  2018. echo shar: End of archive 3 \(of 8\).
  2019. cp /dev/null ark3isdone
  2020. MISSING=""
  2021. for I in 1 2 3 4 5 6 7 8 ; do
  2022.     if test ! -f ark${I}isdone ; then
  2023.     MISSING="${MISSING} ${I}"
  2024.     fi
  2025. done
  2026. if test "${MISSING}" = "" ; then
  2027.     echo You have unpacked all 8 archives.
  2028.     rm -f ark[1-9]isdone
  2029. else
  2030.     echo You still need to unpack the following archives:
  2031.     echo "        " ${MISSING}
  2032. fi
  2033. ##  End of shell archive.
  2034. exit 0
  2035. -- 
  2036. uucp:    mcvax!eutrc3!wswietse    | Eindhoven University of Technology
  2037. bitnet:    wswietse@heithe5    | Dept. of Mathematics and Computer Science
  2038. surf:    tuerc5::wswietse    | Eindhoven, The Netherlands.
  2039.